﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LuaInterface;
using System;

public class ScriptObject
{
	private static int InstanceCounter = 0;

	protected LuaTable m_Table;
	public LuaTable Table => m_Table;
	protected LuaTable m_MetaTable;
	public LuaTable MetaTable => m_MetaTable;

	public string LuaClassName { get; set; } = "";
	public int LuaID { get; set; } = 0;

	//这三项在构造函数中一同赋值  并在Release中清除
	public bool IsValid => m_Table != null && m_MetaTable != null && !string.IsNullOrEmpty(LuaClassName);

	public ScriptObject(string luaName)
	{
		LuaID = InstanceCounter++;
		Construct(luaName, new System.Object[] { });
	}
	public ScriptObject(string luaName, System.Object[] objects)
	{
		LuaID = InstanceCounter++;
		Construct(luaName, objects);
	}

	/// <summary>
	/// 这里设定LuaClass对象创建都是默认调用 luaName.New 函数
	/// 返回值为 LuaTable 
	///		.mt  为 lua中缓存对象 即为所用的源表
	/// </summary>
	protected void Construct(string luaName, object[] objects)
	{
		try
		{
			LuaClassName = luaName;
			using (System.gstring.Block())
			{
				string ctor = System.gstring.Concat(luaName, ".New").ToString();
				
				ScriptManager.Instance.CallFunction(ctor , objects, out object ret);

				if (null != ret) {
					var table = ret as LuaTable;
					m_Table = table;
					m_MetaTable = table.GetTable<LuaTable>("mt");
				}
				
			}
		}
		catch(System.Exception e)
		{
			Debug.LogError($"通过Lua调用构造时发生异常: {e.StackTrace} ");
			this.Release();
		}
	}

	internal bool CallFunc(string funcName, object[] param, out object obj)
	{
		return ScriptManager.Instance.CallFunction(this, funcName, param, out obj);
	}
	internal bool CallFunc(string funcName, object[] param, out object[] objs)
	{
		return ScriptManager.Instance.CallFunction(this, funcName, param, out objs);
	}
	internal bool CallFunc(string funcName, object[] param)
	{
		return ScriptManager.Instance.CallFunction(this, funcName, param);
	}

	public void Release()
	{
		if (m_Table != null)
			m_Table.Dispose();
		this.Clear();
	}
	protected void Clear()
	{
		this.LuaID = 0;
		this.LuaClassName = "";
		this.m_Table = null;
		this.m_MetaTable = null;
	}
}
